package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.DeviceDto;
import com.zzyl.dto.DevicePageQueryDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import org.codehaus.commons.compiler.util.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private Client client;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private DeviceMapper deviceMapper;

    @Override
    public void syncProductList() {
        //请求参数
        QueryProductListRequest request = new QueryProductListRequest();
//       调用第三方查询产品列表
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setPageSize(200);
        request.setCurrentPage(1);
        QueryProductListResponse response=null;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
//        判断,如果数据为空,则中断请求
        if (!response.getBody().success){
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
        //        获取数据,存储至redis
        List<ProductVo> info = response.getBody().getData().getList().getProductInfo().stream().map( p-> BeanUtil.toBean(p,ProductVo.class)).collect(Collectors.toList());
//        获取数据,存储至redis
        redisTemplate.boundValueOps(CacheConstants.ALL_PRODUCT_KEY).set(JSONUtil.toJsonStr(info));
    }

    @Override
    public List<ProductVo> getAllProduct() {

        String jsonDate = redisTemplate.boundValueOps(CacheConstants.ALL_PRODUCT_KEY).get();
        if (jsonDate == null){
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
        List<ProductVo> resout = JSONUtil.toList(jsonDate,ProductVo.class);
        return resout;
    }


    @Override
    public void registerDevice(DeviceDto deviceDto) {

//        设备名称是否重复
        Integer count =deviceMapper.selectCountBy(deviceDto.getDeviceName());
//        重复->结束
        if(count>0){
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
//        IOT新增设备->到物联网平台
        RegisterDeviceRequest request = deviceDto.getRegisterDeviceRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        RegisterDeviceResponse registerDeviceResponse=null;
        try {
            registerDeviceResponse= client.registerDevice(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        if (!registerDeviceResponse.getBody().success){
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
//        获取产品iot_id
        String iotId = registerDeviceResponse.getBody().getData().getIotId();
//        查询产品,获取产品名称
        QueryProductRequest queryProductrequest = new QueryProductRequest();
        queryProductrequest.setProductKey(deviceDto.getProductKey());
        queryProductrequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryProductResponse queryProductResponse = null;
        try {
            queryProductResponse = client.queryProduct(queryProductrequest);
        } catch (Exception e) {
            DeleteByIot(iotId);
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);

        }
        String productName = queryProductResponse.getBody().getData().getProductName();

//        判断位置信息(跟随还是固定)
        if(deviceDto.getLocationType()!=1){
            //        设置跟随->将物理位置设置为-1
            deviceDto.setPhysicalLocationType(-1);
        }
        deviceDto.setIotId(iotId);
        deviceDto.setProductName(productName);
//        保存到数据库
        Device bean = BeanUtil.toBean(deviceDto, Device.class);
        int insert = deviceMapper.insertSelective(bean);
//        保存是否成功
        if (insert<=0){
            DeleteByIot(iotId);
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
//        回退到新增设备之前
    }

    @Override
    public PageResponse getByPage(DevicePageQueryDto dto) {
        PageHelper.startPage(dto.getPageNum(),dto.getPageSize());
        List<Device> devices = deviceMapper.selectByPage(dto);
        PageResponse pageResponse = PageResponse.of(devices);
        return pageResponse;
    }

    @Override
    public DeviceVo queryDeviceDetail(QueryDeviceDetailRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDeviceDetailResponse response;
        try {
            response = client.queryDeviceDetail(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData data = response.getBody().getData();
        DeviceVo deviceVo = BeanUtil.toBean(data, DeviceVo.class);
        DeviceVo deviceSQL= deviceMapper.selectByIotId(request.getIotId());
        BeanUtil.copyProperties(deviceSQL,deviceVo,	CopyOptions.create().ignoreNullValue());
        return deviceVo;
    }

    @Override
    public
    QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData queryThingModelPublished(QueryThingModelPublishedRequest dto) {
        dto.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryThingModelPublishedResponse response;
        try {
            response = client.queryThingModelPublished(dto);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 判断是否获取到数据
        if(response==null|| !response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
        return response.getBody().getData();
    }

    @Override
    public QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData queryDevicePropertyStatus(QueryDevicePropertyStatusRequest dto) {
        dto.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse response;
        try {
            response=client.queryDevicePropertyStatus(dto);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return response.getBody().getData();
    }

    @Override
    public void updateDevice(DeviceDto deviceDto) {

        Device device = BeanUtil.toBean(deviceDto,Device.class);
        deviceMapper.updateByPrimaryKeySelective(device);
    }

    public void DeleteByIot(String iotId){
        DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
        deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        deleteDeviceRequest.setIotId(iotId);
        try {
            client.deleteDevice(deleteDeviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
    }
}
